import 'dart:io';

import 'package:example/utils/common.dart';
import 'package:example/config/const_config.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';

class LocalManage {
  static final LocalManage _singleton = LocalManage._internal();

  factory LocalManage() {
    return _singleton;
  }

  LocalManage._internal();

  SharedPreferences? sp;

  //初始化
  init() async {
    sp = await SharedPreferences.getInstance();
  }

  static SharedPreferences getSp() {
    return LocalManage().sp!;
  }

  static logout() async {

    String? baseUrl = LocalManage.getSp().getString(ConstConfig.baseUrl);
    String? defaultEnv = LocalManage.getSp().getString(ConstConfig.defaultEnv);
    String? ip = LocalManage.getSp().getString(ConstConfig.proxyIP);
    String? host = LocalManage.getSp().getString(ConstConfig.proxyHost);
    await LocalManage.getSp().clear();

    if (isDebug && isNotEmptyOrNull(baseUrl)) {
      await LocalManage.getSp().setString(ConstConfig.baseUrl, baseUrl!);
    }

    if (isNotEmptyOrNull(ip)) {
      await LocalManage.getSp().setString(ConstConfig.proxyIP, ip!);
    }
    if (isNotEmptyOrNull(host)) {
      await LocalManage.getSp().setString(ConstConfig.proxyHost, host!);
    }
    if (isNotEmptyOrNull(defaultEnv)) {
      await LocalManage.getSp().setString(ConstConfig.defaultEnv, defaultEnv!);
    }
  }

  /// 获取缓存目录
  static Future<String> getCachePath({String? directory}) async {
    Directory temp = await getTemporaryDirectory();
    String path = "${temp.absolute.path}/cache";
    Directory cache = Directory(path);
    if (!cache.existsSync()) {
      cache.createSync();
    }
    if (directory != null) {
      path = "$path/$directory";
      Directory cache = Directory(path);
      if (!cache.existsSync()) {
        cache.createSync();
      }
    }

    logger.i("getCachePath -> $path");
    return path;
  }

  /// 获取缓存目录新文件
  static Future<File> getCacheNewFile(
      {String? directory, required String fileName}) async {
    String path = await getCachePath(directory: directory);
    File file = File("$path/$fileName");
    if (!file.existsSync()) {
      file.createSync();
    }
    logger.i("getCacheNewFile -> ${file.path}");
    return file;
  }

  /// 获取缓存大小
  static Future<String> loadCacheSizeStr() async {
    try {
      Directory _tempDir = await getTemporaryDirectory();
      double value = await _getTotalSizeOfFilesInDir(_tempDir);
      /*tempDir.list(followLinks: false,recursive: true).listen((file){
          //打印每个缓存文件的路径
        print(file.path);
      });*/
      logger.i('临时目录大小: ' + value.toString());
      return _renderSize(value);
    } catch (e) {
      logger.e("获取缓存大小失败:$e");
      return Future.error("获取缓存大小失败");
    }
  }

  /// 清除缓存
  static Future clearCache() async {
    showLoading();
    try {
      Directory _tempDir = await getTemporaryDirectory();
      double value = await _getTotalSizeOfFilesInDir(_tempDir);
      logger.i("$value");
      if (value <= 0) {
        logger.i("暂无缓存");
      } else if (value >= 0) {
        await delDir(_tempDir);
      }
    } catch (e) {
      logger.e("清除缓存失败:$e");
      return Future.error("清除缓存失败");
    }
    hideLoading();
  }

  ///递归方式删除目录
  static Future<Null> delDir(FileSystemEntity file) async {
    try {
      if (file is Directory) {
        final List<FileSystemEntity> children = file.listSync();
        for (final FileSystemEntity child in children) {
          await delDir(child);
        }
      }
      await file.delete();
    } catch (e) {
      logger.e("递归方式删除目录失败:$e");
    }
  }

  ///格式化文件大小
  static _renderSize(double? value) {
    if (null == value) {
      return 0;
    }
    List<String> unitArr = []..add('B')..add('K')..add('M')..add('G');
    int index = 0;
    while (value! > 1024) {
      index++;
      value = value / 1024;
    }
    String size = value.toStringAsFixed(2);
    return size + unitArr[index];
  }

  /// 递归方式 计算文件的大小
  static Future<double> _getTotalSizeOfFilesInDir(
      final FileSystemEntity file) async {
    try {
      if (file is File) {
        int length = await file.length();
        return double.parse(length.toString());
      }
      if (file is Directory) {
        final List<FileSystemEntity>? children = file.listSync();
        double total = 0;
        if (children != null)
          for (final FileSystemEntity child in children)
            total += await _getTotalSizeOfFilesInDir(child);
        return total;
      }
      return 0;
    } catch (e) {
      logger.e("获取缓存大小失败:$e");
      return 0;
    }
  }
}
